package com.zzl.ov_library.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zzl.ov_library.dto.Result;
import com.zzl.ov_library.entity.Branch;
import com.zzl.ov_library.entity.Comment;
import com.zzl.ov_library.entity.Reservation;
import com.zzl.ov_library.entity.ReservationVO;
import com.zzl.ov_library.service.BranchService;
import com.zzl.ov_library.service.CommentService;
import com.zzl.ov_library.service.ReservationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.sql.Time;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

@RestController
public class ReservationController {
    @Autowired
    private ReservationService reservationService;

    @Autowired
    private BranchService branchService;

    @Autowired
    private CommentService commentService;

    //新增预约记录
    @PostMapping("/reservation/add")
    public Result addReservation(@RequestParam String userId, @RequestParam String branchId, @RequestParam String day) throws ParseException {
        System.out.println("userId:" + userId + "branchId:" + branchId + "day:" + day);
        //获取当前年月
        LocalDate now = LocalDate.now();
        String reserveTime = now.getYear() + "-" + now.getMonthValue() + "-" + day;
        //通过userId和reserveTime查询预约记录是否已存在
        List<Reservation> list = reservationService.list(Wrappers.lambdaQuery(Reservation.class)
                .eq(Reservation::getUserId, userId)
                .eq(Reservation::getReserveTime, reserveTime));
        //判断预约记录是否存在
        if (!list.isEmpty()) {
            //遍历预约记录，如果预约记录已存在，且预约状态为待签到或已签到，则预约失败
            for (Reservation reservation : list) {
                if (reservation.getStatus().equals("待签到") || reservation.getStatus().equals("已签到")) {
                    return Result.fail().setMsg("当日预约次数已达上限");
                }
            }
        }

        //通过branchId获取分馆信息
        Branch branch = branchService.getById(branchId);
        //获取当前时间，如果当前时间大于分馆的结束时间，则预约失败
        LocalTime nowTime = LocalTime.now();
        System.out.println("nowDate:" + nowTime);
        System.out.println("branch.getEndTime:" + branch.getEndTime());
        if (nowTime.isAfter(branch.getEndTime().toLocalTime())) {
            return Result.fail().setMsg("预约时间已过");
        }
        //获取分馆最大预约数
        Integer max = branch.getMax();
        //查询当前分馆当天所有预约记录数量,并且状态不是“已取消”
        Long count = reservationService.count(Wrappers.lambdaQuery(Reservation.class)
                .eq(Reservation::getBranchId, branchId)
                .eq(Reservation::getReserveTime, reserveTime)
                .in(Reservation::getStatus, "待签到", "已签到"));
        if (count >= max) {
            return Result.fail().setMsg("该分馆预约人数已满");
        }
        Reservation reservation = new Reservation();
        reservation.setUserId(Integer.parseInt(userId));
        reservation.setBranchId(Integer.parseInt(branchId));

        //将reserveTime转换为Date格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = sdf.parse(reserveTime);

        reservation.setReserveTime(date);
        System.out.println(reservation);
        return reservationService.save(reservation) ? Result.ok().setMsg("预约成功") : Result.fail().setMsg("预约失败");
    }

    //预约信息列表，按userId与状态搜索
    @GetMapping("/reservation/list")
    public Result list(@PathVariable Integer userId, @PathVariable Object status) {
        List<Reservation> List = reservationService.list(Wrappers.lambdaQuery(Reservation.class)
                .eq(Reservation::getUserId, userId)
                .eq(Reservation::getStatus, status));
        return Result.ok().setData(List).setMsg("查询成功");
    }

    //查询已签到与已取消的预约记录，即历史预约记录
    @GetMapping("/reservation/history")
    public Result history(@RequestParam Integer userId) {
        LocalDate now = LocalDate.now();
        String reserveTime = now.getYear() + "-" + now.getMonthValue() + "-" + (now.getDayOfMonth() - 1);
        //按预约时间降序排序
        List<Reservation> list = reservationService.list(
                Wrappers.lambdaQuery(Reservation.class)
                        .eq(Reservation::getUserId, userId)
                        .and(wrapper -> wrapper
                                .in(Reservation::getStatus, "已签到", "已取消")
                                .or(subWrapper -> subWrapper
                                        .eq(Reservation::getStatus, "待签到")
                                        .le(Reservation::getReserveTime, reserveTime)
                                )
                        )
                        .orderByDesc(Reservation::getReserveTime)
        );
        return Result.ok().setData(getResult(list)).setMsg("查询成功");
    }

    //查询未签到且预约日期在今天之前的预约记录，即违约记录
    @GetMapping("/reservation/default")
    public Result defaultList(@RequestParam Integer userId) {
        LocalDate now = LocalDate.now();
        String reserveTime = now.getYear() + "-" + now.getMonthValue() + "-" + now.getDayOfMonth();
        List<Reservation> list = reservationService.list(Wrappers.lambdaQuery(Reservation.class)
                .eq(Reservation::getUserId, userId)
                .eq(Reservation::getStatus, "待签到")
                .le(Reservation::getReserveTime, reserveTime)
                .orderByDesc(Reservation::getReserveTime));

        return Result.ok().setData(getResult(list)).setMsg("查询成功");
    }

    //查询未签到且预约日期在今天及之后的预约记录，即当前预约记录
    @GetMapping("/reservation/current")
    public Result current(@RequestParam Integer userId) {
        LocalDate now = LocalDate.now();
        String reserveTime = now.getYear() + "-" + now.getMonthValue() + "-" + now.getDayOfMonth();
        List<Reservation> list = reservationService.list(Wrappers.lambdaQuery(Reservation.class)
                .eq(Reservation::getUserId, userId)
                .eq(Reservation::getStatus, "待签到")
                .ge(Reservation::getReserveTime, reserveTime));
        return Result.ok().setData(getResult(list)).setMsg("查询成功");
    }

    //Reservation类转ReservationVO类
    public List<ReservationVO> getResult(List<Reservation> list) {
        //遍历List，通过branchId获取branchName，并设置到ReservationVO中
        List<ReservationVO> reservationVOList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Branch branch = branchService.getById(list.get(i).getBranchId());
            String branchName = branch.getBranchName();
            Time startTime = branch.getStartTime();
            Time endTime = branch.getEndTime();
            ReservationVO reservationVO = new ReservationVO();
            reservationVO.setBranchName(branchName);
            reservationVO.setStartTime(startTime);
            reservationVO.setEndTime(endTime);
            reservationVO.setReserveId(list.get(i).getReserveId());
            reservationVO.setBranchId(list.get(i).getBranchId());
            reservationVO.setReserveTime(list.get(i).getReserveTime());
            reservationVO.setUserId(list.get(i).getUserId());
            reservationVO.setStatus(list.get(i).getStatus());
            reservationVOList.add(reservationVO);
            //通过reserveId获取Comment对象，判断是否有评论
            Comment comment = commentService.getOne(Wrappers.lambdaQuery(Comment.class)
                    .eq(Comment::getReserveId, list.get(i).getReserveId()));
            if (comment != null) {
                reservationVOList.get(i).setComment(comment.getContent());
                reservationVOList.get(i).setReplay(comment.getReplay());
                reservationVOList.get(i).setReplayTime(comment.getReplayTime());
                reservationVOList.get(i).setCommentId(comment.getId());
            }
        }
        System.out.println("reservationVOList:" + reservationVOList);
        return reservationVOList;
    }


    //签到
    @PutMapping("/reservation/signIn")
    public Result signIn(@RequestParam Integer reserveId) {
        //通过reserveId获取Reservation对象
        Reservation reservation = reservationService.getById(reserveId);
        //获取当前时间，判断是否与reserveTime相等，若相等则签到，否则签到失败
        LocalDate now = LocalDate.now();
        String reserveTime1 = reservation.getReserveTime().toLocaleString().substring(0, 10);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年M月d日", Locale.CHINA);
        LocalDate reserveTime = LocalDate.parse(reserveTime1, formatter);

        if (!now.equals(reserveTime)) {
            return Result.fail().setMsg("签到失败，签到日期与预约日期不一致");
        }
        reservation.setStatus("已签到");
        return reservationService.updateById(reservation) ? Result.ok().setMsg("签到成功") : Result.fail().setMsg("签到失败");

    }

    //取消预约
    @PutMapping("/reservation/cancel")
    public Result cancel(@RequestParam Integer reserveId) {
        // 通过reserveId获取Reservation对象
        Reservation reservation = reservationService.getById(reserveId);
        if (reservation == null) {
            return Result.fail().setMsg("预约不存在");
        }

        // 获取当前日期
        LocalDate now = LocalDate.now();

        // 将 java.util.Date 转换为 LocalDate
        Date reserveDate = reservation.getReserveTime();
        Instant instant = reserveDate.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDate reserveTime = instant.atZone(zoneId).toLocalDate();

        // 判断是否已经是预约当天
        if (now.equals(reserveTime)) {
            return Result.fail().setMsg("取消失败，已经过了最晚可取消时间");
        }

        // 设置状态并更新
        reservation.setStatus("已取消");
        return reservationService.updateById(reservation)
                ? Result.ok().setMsg("取消成功")
                : Result.fail().setMsg("取消失败");
    }


}
